package com.eveinfo.display;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import android.app.Activity;
import android.app.AlertDialog;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.text.Html;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView;

import com.eveinfo.EveInfo;
import com.eveinfo.R;
import com.eveinfo.api.ApiException;
import com.eveinfo.api.NoCacheFoundExecption;
import com.eveinfo.api.accessors.Assets;
import com.eveinfo.api.accessors.SkillQueue;
import com.eveinfo.api.asset.ApiAsset;
import com.eveinfo.api.asset.AssetResponse;
import com.eveinfo.api.character.sheet.ApiKnownSkill;
import com.eveinfo.api.character.sheet.ApiSheet;
import com.eveinfo.api.character.skillqueue.ApiSkillQueue;
import com.eveinfo.api.character.skilltraining.ApiSkillTraining;
import com.eveinfo.display.planner.PlannerManager;
import com.eveinfo.sql.DataBaseHelper;
import com.eveinfo.sql.data.Item;
import com.eveinfo.sql.data.Station;
import com.eveinfo.tools.ActivityLauncher;
import com.eveinfo.tools.EveInfoMenu;
import com.eveinfo.tools.Logging;
import com.eveinfo.tools.Tools;
import com.eveinfo.tools.TrainingSkillCountDown;
import com.eveinfo.update.CharacterData;
import com.eveinfo.update.DataChangedListener;

public class SheetView extends Activity implements DataChangedListener {

	private final Activity activity;

	private Bitmap imageBitmap;

	private ApiSheet sheet;
	private ApiSkillTraining skillTraining;
	private SkillQueue skillQueue;

	private static PlannerManager plannerManager;
	private static ArrayList<Item> items;
	private static ArrayList<Station> stations;

	private static Thread assetsThread;
	private static Exception assetsException;
	private int characterID;

	private TextView factionTV;
	private TextView textViewISK;
	private TextView textViewInfo;
	private TextView textViewSheetTraining;
	private TextView textViewSheetQueue;
	private TextView textViewCountDown;

	public SheetView() {
		this.activity = this;
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.sheet);

		characterID = getIntent().getIntExtra("characterID", 0);
		final CharacterData characterData = EveInfo.getData().getCharacterData(characterID);
		sheet = characterData.getSheet();
		skillTraining = characterData.getSkillTraining();
		skillQueue = characterData.getSkillQueue();

		if (sheet == null) {
			// TODO
			finish();
			return;
		}

		assetsException = null;
		if (items == null || stations == null) {
			assetsThread = new Thread() {
				public void run() {
					try {
						loadAssets();
					} catch (Exception e) {
						assetsException = e;
					}
				};
			};
			assetsThread.start();
		}
		plannerManager = new PlannerManager(this, sheet.getName());

		imageBitmap = Tools.getCharacterImageBitmap(sheet.getCharacterID(), false);

		try {
			final ImageView imageView = (ImageView) findViewById(R.id.IVSheet);
			imageView.setImageBitmap(imageBitmap);

			TextView nameTV = (TextView) findViewById(R.id.TVSheetName);
			nameTV.setText(sheet.getName());

			factionTV = (TextView) findViewById(R.id.TVSheetFaction);
			textViewISK = (TextView) findViewById(R.id.TVSheetISK);
			textViewInfo = (TextView) findViewById(R.id.TVSheetInfo);
			textViewSheetTraining = (TextView) findViewById(R.id.TVSheetTraining);
			textViewSheetQueue = (TextView) findViewById(R.id.TVSheetQueue);
			textViewCountDown = (TextView) findViewById(R.id.TVSheetCountDown);

			initSheetUI();

		} catch (Exception e) {
			Logging.getInstance().e(e);
			e.printStackTrace();
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle(e.toString());
			builder.setMessage(e.getMessage());
			builder.show();
			finish();
		}
	}

	private void initSheetUI() {
		/* ISK display */
		textViewISK.setText(Tools.getFormat().format(sheet.getBalance()) + " ISK");

		/* Player faction/corpo Infomations display */
		StringBuilder sb = new StringBuilder();
		sb.append(sheet.getGender() + " " + sheet.getRace() + " " + sheet.getBloodLine() + "\n");
		sb.append(sheet.getCorporationName());
		factionTV.setText(sb.toString());

		/* Player skills Infomations display */
		Collection<ApiKnownSkill> skills = sheet.getSkills().values();
		Double spCount = new Double(0);
		int skillV = 0;
		for (ApiKnownSkill skill : skills) {
			spCount += skill.getSkillpoints();
			if (skill.getLevel() == 5)
				skillV++;
		}
		sb.setLength(0);
		sb.append(skills.size() + " Known Skills\n");
		sb.append(Tools.getFormat().format(spCount) + " Total SP\n");
		sb.append(skillV + " Skills at Lvl 5");
		textViewInfo.setText(sb.toString());

		sb.setLength(0);
		if (skillTraining.isSkillInTraining()) {
			sb.append("Currently Training:<br/><br/>");
			sb.append("<big><b>" + EveInfo.getData().getSkills().getSkillName(skillTraining.getTrainingTypeID()) + " "
					+ skillTraining.getTrainingToLevel() + "</b></big>");
			TrainingSkillCountDown remain = new TrainingSkillCountDown(textViewCountDown,
					skillTraining.getRemainTime(), 1000);
			remain.start();
			textViewSheetTraining.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					ActivityLauncher.displaySkill(activity, skillTraining.getTrainingTypeID(), sheet.getCharacterID());
				}
			});

		}
		textViewSheetTraining.setText(Html.fromHtml(sb.toString()));

		if (this.skillQueue != null) {
			final ArrayList<ApiSkillQueue> skillQueue = this.skillQueue.getSkillQueue();
			if (skillQueue.size() > 0 && !(skillQueue.size() == 1 && skillTraining.isSkillInTraining())) {
				sb.setLength(0);
				sb.append("Skills Queue :<br/>");
				for (ApiSkillQueue skill : skillQueue) {
					if (skill.getPosition() > 0 || !skillTraining.isSkillInTraining()) {
						sb.append("<big><b>" + EveInfo.getData().getSkills().getSkillName(skill.getTrainingTypeID())
								+ " " + skill.getTrainingToLevel() + "</b></big><br/>");
					}
				}
				textViewSheetQueue.setText(Html.fromHtml(sb.toString()));
			}
		}
	}

	public static PlannerManager getPlannerManager() {
		return plannerManager;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0, EveInfoMenu.MENU_CHAR_SKILLS, 0, EveInfoMenu.MENU_CHAR_SKILLS_NAME)
				.setIcon(R.drawable.icon22_41_32);
		menu.add(0, EveInfoMenu.MENU_WALLET, 0, EveInfoMenu.MENU_WALLET_NAME).setIcon(R.drawable.icon07_12_32);
		menu.add(0, EveInfoMenu.MENU_CERTIFICATES, 0, EveInfoMenu.MENU_CERTIFICATES_NAME).setIcon(
				R.drawable.icon79_01_32);
		menu.add(0, EveInfoMenu.MENU_PLANNERS, 0, EveInfoMenu.MENU_PLANNERS_NAME).setIcon(R.drawable.icon06_02_32);
		menu.add(0, EveInfoMenu.MENU_ATTRIBUTES, 0, EveInfoMenu.MENU_ATTRIBUTES_NAME).setIcon(R.drawable.icon25_14_32);
		menu.add(0, EveInfoMenu.MENU_ASSETS, 0, EveInfoMenu.MENU_ASSETS_NAME).setIcon(R.drawable.icon07_13_32);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case EveInfoMenu.MENU_WALLET:
			ActivityLauncher.displayWallet(this, characterID);
			return true;
		case EveInfoMenu.MENU_CHAR_SKILLS:
			ActivityLauncher.displaySkills(this, characterID);
			return true;
		case EveInfoMenu.MENU_CERTIFICATES:
			ActivityLauncher.displayCategories(this, characterID);
			return true;
		case EveInfoMenu.MENU_PLANNERS:
			ActivityLauncher.displayPlanner(this, characterID);
			return true;
		case EveInfoMenu.MENU_ATTRIBUTES:
			ActivityLauncher.displayAttributes(this, characterID);
			return true;
		case EveInfoMenu.MENU_ASSETS:
			return EveInfoMenu.displayView(this, EveInfoMenu.View.ASSETS);
		default:
			return false;
		}
	}

	private void loadAssets() throws IOException, SAXException, ParserConfigurationException, ApiException,
			NoCacheFoundExecption {
		if (sheet == null)
			return;
		AssetResponse apiSheet = new Assets(sheet.getUserId(), sheet.getCharacterID(), sheet.getApiKey())
				.getAssetResponse();
		items = new ArrayList<Item>();
		stations = new ArrayList<Station>();

		HashMap<Integer, Item> itemsHM = new HashMap<Integer, Item>();
		HashMap<Integer, Station> stationsHM = new HashMap<Integer, Station>();

		DataBaseHelper dataBaseHelper = new DataBaseHelper(this);
		dataBaseHelper.openDataBase();
		ArrayList<ApiAsset> assets = apiSheet.getAssets();
		int size = assets.size();

		for (int i = 0; i < size; i++) {
			ApiAsset asset = assets.get(i);
			Item item = itemsHM.get(asset.getTypeID());
			if (item == null) {
				item = dataBaseHelper.getItem(asset.getTypeID());
				if (item == null) {
					continue;
				}
				itemsHM.put(item.getTypeID(), item);
			}
			asset.setItem(item);
			item.addAsset(asset);
			final int locationID = asset.getLocationID();
			Station station = stationsHM.get(locationID);
			if (station == null) {
				station = new Station(dataBaseHelper.getStationName(locationID));
				stationsHM.put(locationID, station);
			}
			station.addAsset(asset);
		}
		dataBaseHelper.close();
		items.addAll(itemsHM.values());
		stations.addAll(stationsHM.values());
		Collections.sort(stations);
	}

	public static ArrayList<Item> getItems() throws Exception {
		if (assetsThread.isAlive()) {
			try {
				assetsThread.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
				return null;
			}
		}
		if (assetsException != null) {
			throw new Exception(assetsException);
		}
		return items;
	}

	public static ArrayList<Station> getStations() throws Exception {
		if (assetsThread.isAlive()) {
			try {
				assetsThread.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
				return null;
			}
		}
		if (assetsException != null) {
			throw new Exception(assetsException);
		}
		return stations;
	}

	@Override
	public void datasChanged(List<CharacterData> characterDatas) {
		final int size = characterDatas.size();
		for (int i = 0; i < size; i++) {
			CharacterData character = characterDatas.get(i);
			final ApiSheet sheet = character.getSheet();
			if (sheet.getCharacterID() == characterID) {
				this.sheet = sheet;
				initSheetUI();
				return;
			}
		}
	}
}
